package cn.cocho.dborm.core;

import java.util.List;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;
import android.util.Pair;

import cn.cocho.dborm.util.LoggerUtilsDborm;
import cn.cocho.dborm.util.DbormContexts;
import cn.cocho.dborm.util.StringUtilsDborm;

/**
 * 连接数据库及执行SQL
 * 
 * @author dborm@cocho
 * @time 2013-5-6上午10:40:40
 */
public class SQLExcuter {

	/**
	 * 执行SQL(并作SQL检查及输出)
	 * 
	 * @param sql
	 *            sql语句
	 * @param bindArgs
	 *            该SQL语句所需的参数
	 * @param database
	 *            数据库连接
	 * @throws Exception
	 * @author dborm@cocho
	 * @time 2013-6-7下午2:54:48
	 */
	public static void execSQL(String sql, Object[] bindArgs, SQLiteDatabase database) throws Exception {
		checkSql(sql, bindArgs);
		try {
			database.execSQL(sql);
		} catch (Exception e) {
			throw e;
		} finally {
			closeDatabase(database);
		}
	}

	/**
	 * 批量执行SQL，在事务中完成
	 * 
	 * @param execSqlPairList
	 *            第一个参数为SQL语句， 第二个参数为SQL语句所需的参数
	 * @param database
	 *            数据库连接
	 * @throws Exception
	 * @author dborm@cocho
	 * @time 2013-5-6上午10:41:26
	 */
	public static void execSQLUseTransaction(List<Pair<String, Object[]>> execSqlPairList, SQLiteDatabase database) throws Exception {
		try {
			database.beginTransaction();
			for (int i = 0; i < execSqlPairList.size(); i++) {
				Pair<String, Object[]> pair = execSqlPairList.get(i);
				checkSql(pair.first, pair.second);
				if (pair.second == null) {
					database.execSQL(pair.first, new Object[] {});
				} else {
					database.execSQL(pair.first, pair.second);
				}
			}
			database.setTransactionSuccessful();// 设置事务标志为成功，当结束事务时就会提交事务
		} catch (Exception e) {
			throw e;
		} finally {
			database.endTransaction();
		}

	}

	/**
	 * 查询操作
	 * 
	 * @param sql
	 *            查询语句
	 * @param selectionArgs
	 *            查询语句所需的参数
	 * @param database
	 *            数据库连接
	 * @return 查询结果集或null
	 * @throws Exception
	 * @author dborm@cocho
	 * @time 2013-5-6上午10:43:44
	 */
	public static Cursor rawQuery(String sql, Object[] selectionArgs, SQLiteDatabase database) throws Exception {
		checkSql(sql, selectionArgs);
		if (selectionArgs == null) {
			return database.rawQuery(sql, new String[] {});
		} else {
			return database.rawQuery(sql, objectArrayToString(selectionArgs));
		}
	}

	private static String[] objectArrayToString(Object[] selectionArgs) {
		String[] args = new String[selectionArgs.length];
		for (int i = 0; i < selectionArgs.length; i++) {
			Object obj = selectionArgs[i];
			if (obj != null) {
				args[i] = obj.toString();
			} else {
				args[i] = null;
			}
		}
		return args;
	}

	/**
	 * 检查SQL语句并做日志记录
	 * 
	 * @param sql
	 *            sql语句
	 * @param bindArgs
	 *            sql语句所绑定的参数
	 * @author dborm@cocho
	 * @time 2013-5-7上午10:55:38
	 */
	private static void checkSql(String sql, Object[] bindArgs) {
		if (StringUtilsDborm.isNotBlank(sql)) {
			if (DbormContexts.showSql) {
				StringBuilder sqlContent = new StringBuilder("运行的SQL语句如下：\n");
				sqlContent.append(sql);
				if (bindArgs != null) {
					sqlContent.append("\n所需的参数如下：\n");
					int size = bindArgs.length;
					for (int i = 0; i < size; i++) {
						sqlContent.append(bindArgs[i]);
						if (i + 1 != size) {
							sqlContent.append(",");
						}
					}
				}
				LoggerUtilsDborm.debug(sqlContent.toString());
			}
		} else {
			throw new IllegalArgumentException("需要执行的SQL语句不能为空!");
		}
	}

	/**
	 * 关闭数据库连接
	 * 
	 * @param database
	 * @author HAIKANG SONG
	 * @time 2013-5-6上午10:47:29
	 */
	public static void closeDatabase(SQLiteDatabase database) {
		if (database != null) {
			database.close();
			database = null;
		}
	}

	public static void closeCursor(Cursor cursor) {
		if (cursor != null) {// TODO 关游标的时候是否会导致数据库关闭
			cursor.close();
			cursor = null;
		}
	}

	/**
	 * 获得数据库连接
	 * 
	 * @return
	 * @author HAIKANG SONG
	 * @time 2013-5-6上午10:46:44
	 */
	// private SQLiteDatabase getSQLiteDatabase() {
	// String dbFilePath = DbormContexts.getDbFilePath();
	// if (StringUtils.isBlank(dbFilePath)) {
	// throw new
	// RuntimeException("数据库路径不能为空，请使用DbormContexts.setDbFilePath（[path]）设置.");
	// }
	//
	// File dbFile = new File(DbormContexts.getDbFilePath());
	// if (!dbFile.exists()) {
	// new File(dbFile.getParent()).mkdirs();
	// }
	// SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(dbFile,
	// null);
	// return database;
	// }

}
